/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>

#include "glm/glm.hpp"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include <GLES3/gl3.h>
#include <glm/gtc/matrix_transform.hpp>
#include <hilog/log.h>
#include <memory>

#include <glm/gtc/type_ptr.hpp>

#include "../common/common.h"
#include "loader.h"
#include "plugin_render.h"
#include "renderInterface.h"
#include "tinyobj.h"
#include "trackballManipulator.h"
#include <chrono>
#include <cstdlib>
#include <ctime>
#include <future>
#include <glm/glm.hpp>
#include <random>
#include <string>


glm::vec4 hexToGlmVec3(const std::string &hexColor) {

    std::string cleanedHex = hexColor.substr(1); // 去除'#'
    size_t length = cleanedHex.length();

    // 提取各分量的十六进制字符串
    std::string redStr = cleanedHex.substr(0, 2);
    std::string greenStr = cleanedHex.substr(2, 2);
    std::string blueStr = cleanedHex.substr(4, 2);

    // 转换为十进制整数（0-255）
    int r = std::stoi(redStr, nullptr, 16);
    int g = std::stoi(greenStr, nullptr, 16);
    int b = std::stoi(blueStr, nullptr, 16);

    // 归一化到[0, 1]并返回glm::vec3
    return glm::vec4(static_cast<float>(r) / 255.0f, static_cast<float>(g) / 255.0f, static_cast<float>(b) / 255.0f,
                     1.0f);
}

glm::vec4 randomVec4(float minVal = 0.0f, float maxVal = 1.0f) {
    // 随机数生成器
    static std::random_device rd;
    static std::mt19937 gen(rd());
    std::uniform_real_distribution<float> dis(minVal, maxVal);

    // 返回随机向量
    return glm::vec4(dis(gen), dis(gen), dis(gen), 1);
}
bool EGLCore::EglContextInit(void *window, int width, int height) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "EglContextInit execute");
    if ((nullptr == window) || (0 >= width) || (0 >= height)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "EglContextInit: param error");
        return false;
    }

    m_width = width;
    m_height = height;
    if (0 < m_width) {
        m_widthPercent = FIFTY_PERCENT * m_height / m_width;
    }
    m_eglWindow = static_cast<EGLNativeWindowType>(window);

    // Init display.
    m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (EGL_NO_DISPLAY == m_eglDisplay) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglGetDisplay: unable to get EGL display");
        return false;
    }

    EGLint majorVersion;
    EGLint minorVersion;
    if (!eglInitialize(m_eglDisplay, &majorVersion, &minorVersion)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglInitialize: unable to get initialize EGL display");
        return false;
    }

    // Select configuration.
    const EGLint maxConfigSize = 1;
    EGLint numConfigs;
    if (!eglChooseConfig(m_eglDisplay, ATTRIB_LIST, &m_eglConfig, maxConfigSize, &numConfigs)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglChooseConfig: unable to choose configs");
        return false;
    }

    return CreateEnvironment();
}
void EGLCore::SetManipulator(std::shared_ptr<Manipulator> manipulator) { m_Manipulator = manipulator; }

bool EGLCore::CreateEnvironment() {
    // Create surface.
    if (nullptr == m_eglWindow) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "m_eglWindow is null");
        return false;
    }
    m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, m_eglWindow, NULL);

    if (nullptr == m_eglSurface) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglCreateWindowSurface: unable to create surface");
        return false;
    }

    // Create context.
    m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);
    if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglMakeCurrent failed");
        return false;
    }

    // Create program.
    m_Program = std::make_shared<Program>(VERTEX_SHADER, FRAGMENT_SHADER);
    if (PROGRAM_ERROR == m_Program->GetProgram()) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "CreateProgram: unable to create program");
        return false;
    }
    m_NeuronProgram = std::make_shared<Program>(NEURON_VERTEX_SHADER, NEURON_FRAGMENT_SHADER);
    if (PROGRAM_ERROR == m_NeuronProgram->GetProgram()) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "CreateProgram: unable to create program");
        return false;
    }
    m_SomaProgram = std::make_shared<Program>(SOMA_VERTEX_SHADER, SOMA_FRAGMENT_SHADER);
    if (PROGRAM_ERROR == m_NeuronProgram->GetProgram()) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "CreateProgram: unable to create program");
        return false;
    }

    this->SetManipulator(std::make_shared<TrackballManipulator>(m_width, m_height));
    projection = glm::perspective(glm::radians(60.0f),              // 视角
                                  (float)m_width / (float)m_height, // 宽高比
                                  m_near, m_far                     // 近截面和远截面
    );
//    MainThreadLoop();
    return true;
}
void EGLCore::SetSpecies(const char *species) { m_Species = species; }

void EGLCore::Draw() {
    m_flag = false;
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "Draw");
    PrepareDraw();
    if (m_Species == "monkey")
        this->LoadObj("/data/storage/el2/base/haps/entry/files/monkey.obj");
//        this->LoadObj("/data/app/el2/100/base/NeuronView.1.0/haps/entry/files/monkey.obj");
    else
        this->LoadObj("/data/storage/el2/base/haps/entry/files/997.obj");

    if (m_Manipulator) {
        m_Manipulator->handle();
    }

    if (!ExecuteDraw(DRAW_COLOR)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw rectangle failed");
        return;
    }

    if (!FinishDraw()) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw FinishDraw failed");
        return;
    }

    m_flag = true;
}
void EGLCore::loaderCallback(std::shared_ptr<Geometry> neuron, const char *color, const char *path) {
    if (neuron) {
        GLuint vaotemp, vbotemp[2];
        glUseProgram(m_NeuronProgram->GetProgram());
        glGenVertexArrays(1, &vaotemp);
        glBindVertexArray(vaotemp);

        glGenBuffers(1, &vbotemp[0]);
        // axon
        if (neuron) {

            glBindBuffer(GL_ARRAY_BUFFER, vbotemp[0]);
            glBufferData(GL_ARRAY_BUFFER, neuron->GetVertexSize(Property::Vertex) * sizeof(glm::vec3),
                         neuron->GetVertexPoint(Property::Vertex), GL_STATIC_DRAW);
            auto vec3prop =
                std::dynamic_pointer_cast<PropertyType<glm::vec3>>(neuron->GetVertex()->GetProperty(Property::Vertex));
            if (vec3prop) {
                std::vector<glm::vec3> vectmp;
                vec3prop->m_Data.swap(vectmp);
            }
            GLint positionloc = glGetAttribLocation(m_NeuronProgram->GetProgram(), "a_position");
            glVertexAttribPointer(positionloc, 3, GL_FLOAT, GL_FALSE, 0, 0);
            glEnableVertexAttribArray(positionloc);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
        // soma
        GLuint vao_soma;
        auto soma = neuron->GetChildren()[0];
        Geometry *somageometry = dynamic_cast<Geometry *>(soma.get());
        if (somageometry) {
            glUseProgram(m_SomaProgram->GetProgram());
            glGenVertexArrays(1, &vao_soma);
            glBindVertexArray(vao_soma);

            glGenBuffers(1, &vbotemp[1]);
            glBindBuffer(GL_ARRAY_BUFFER, vbotemp[1]);
            glBufferData(GL_ARRAY_BUFFER, somageometry->GetVertexSize(Property::Vertex) * sizeof(glm::vec3),
                         somageometry->GetVertexPoint(Property::Vertex), GL_STATIC_DRAW);
            auto vec3prop = std::dynamic_pointer_cast<PropertyType<glm::vec3>>(
                somageometry->GetVertex()->GetProperty(Property::Vertex));
            if (vec3prop) {
                std::vector<glm::vec3> vectmp;
                vec3prop->m_Data.swap(vectmp);
            }
            GLint positionloc = glGetAttribLocation(m_SomaProgram->GetProgram(), "a_position");
            glVertexAttribPointer(positionloc, 3, GL_FLOAT, GL_FALSE, 0, 0);
            glEnableVertexAttribArray(positionloc);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
        glm::vec4 color2 = hexToGlmVec3(std::string(color));
        m_NeuronGeo[path] = {neuron, color2, vaotemp, vbotemp[0], vao_soma, vbotemp[1]};
        this->Draw();
    }
}

// void EGLCore::loaderThread(const char *path, Callback callback) {
//     std::shared_ptr<SWCLoader> loader = std::make_shared<SWCLoader>();
//     std::shared_ptr<Geometry> neuron;
//     neuron = loader->load(path);
//
//    
//     callback(neuron, path);
// };
// void EGLCore::AddNeuron(const char *sampleid, const char *neuronname, const char *path) {
//
//     auto iter = m_NeuronGeo.find(path);
//     if (iter == m_NeuronGeo.end()) {
//
//         this->loaderThread(
//             path, [this](std::shared_ptr<Geometry> neuron, const char *p) { this->loaderCallback(neuron,
//                         p); });
//     }
// }
void EGLCore::removeNeuron(const char *sampleid, const char *neuronname, const char *path) {
    auto iter = m_NeuronGeo.find(path);
    if (iter != m_NeuronGeo.end()) {
        glBindBuffer(GL_ARRAY_BUFFER, iter->second.vbo);
        glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STATIC_DRAW);
        glDeleteVertexArrays(1, &iter->second.vao);
        glDeleteBuffers(1, &iter->second.vbo);
        m_NeuronGeo.erase(iter);
//        this->Draw();
    }
}
void EGLCore::selectNeuron(const char *sampleid, const char *neuronname, const char *path) {
    for(auto iter=m_NeuronGeo.begin();iter!=m_NeuronGeo.end();iter++){
        iter->second.selected=false;
    }
    auto iter = m_NeuronGeo.find(path);
    
    if (iter != m_NeuronGeo.end()) {
        iter->second.selected=true;
        m_selectMode = true;
    }else{
        m_selectMode=false;
    }
    this->Draw();
}

void EGLCore::LoadObj(const char *path) {
    if (!m_Geometry) {
        std::shared_ptr<Loader> loader = std::make_shared<Loader>();
        m_Geometry = loader->load(path);
        if (!m_Geometry->GetVertex())
            return;
        m_Geometry->GetVertex()->GetProperty(Property::Vertex);
        auto p = m_Geometry->GetVertexPoint(Property::Normal);
        auto size = m_Geometry->GetVertexSize(Property::Vertex);
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
        glGenBuffers(2, &vbo[0]);
        glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
        glBufferData(GL_ARRAY_BUFFER, m_Geometry->GetVertexSize(Property::Vertex) * sizeof(float),
                     m_Geometry->GetVertexPoint(Property::Vertex), GL_STATIC_DRAW);
        GLint positionloc = glGetAttribLocation(m_Program->GetProgram(), "a_position");
        glEnableVertexAttribArray(positionloc);
        glVertexAttribPointer(positionloc, 3, GL_FLOAT, GL_FALSE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
        glBufferData(GL_ARRAY_BUFFER, m_Geometry->GetVertexSize(Property::Normal) * sizeof(float),
                     m_Geometry->GetVertexPoint(Property::Normal), GL_STATIC_DRAW);

        GLint normLoc = glGetAttribLocation(m_Program->GetProgram(), "normal");
        glEnableVertexAttribArray(normLoc);
        glVertexAttribPointer(normLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        float bboxsize = glm::distance(m_Geometry->GetBBox().min, m_Geometry->GetBBox().max) / 1.5;
        view = glm::lookAt(m_Geometry->GetBBox().getCenter() + glm::vec3(0, 0, bboxsize),
                           m_Geometry->GetBBox().getCenter(), glm::vec3(0, 1.0, .0));
    }
}

GLint EGLCore::PrepareDraw() {
    if ((nullptr == m_eglDisplay) || (nullptr == m_eglSurface) || (nullptr == m_eglContext) ||
        (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "PrepareDraw: param error");
        return POSITION_ERROR;
    }

    // The gl function has no return value.
    glViewport(DEFAULT_X_POSITION, DEFAULT_X_POSITION, m_width, m_height);
    glClearColor(0.0, 0.0, 0.0, GL_ALPHA_DEFAULT);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(m_Program->GetProgram());

    return 0;
}

bool EGLCore::ExecuteDraw(const GLfloat *color) {
    auto manipulator = dynamic_cast<TrackballManipulator *>(m_Manipulator.get());
    auto mat1 = glm::mat4(1.f);
    auto mat2 = glm::rotate(glm::mat4(1.f), glm::radians(180.0f), glm::vec3(1.0, 0.0, 0.0));

    model = glm::translate(mat1, m_Geometry->GetBBox().getCenter()) * manipulator->GetMatrix() * mat2 *
            glm::translate(mat1, -m_Geometry->GetBBox().getCenter());

    float bboxsize = glm::distance(m_Geometry->GetBBox().min, m_Geometry->GetBBox().max) / 1.5;
    view = glm::lookAt(m_Geometry->GetBBox().getCenter() + glm::vec3(0, 0, bboxsize) * manipulator->GetScale(),
                       m_Geometry->GetBBox().getCenter(), glm::vec3(0, 1.0, .0));

    // 获取矩阵的统一变量位置
    GLint modelLoc = glGetUniformLocation(m_Program->GetProgram(), "model");
    GLint viewLoc = glGetUniformLocation(m_Program->GetProgram(), "view");
    GLint projLoc = glGetUniformLocation(m_Program->GetProgram(), "projection");
    glUseProgram(m_Program->GetProgram());

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);
    glBindVertexArray(vao);

    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

    glVertexAttrib4fv(1, color);

    glDrawArrays(GL_TRIANGLES, 0, m_Geometry->GetVertexSize(Property::Vertex) / 3);

    glLineWidth(2);
    // 获取矩阵的统一变量位置
    for (auto iter = m_NeuronGeo.begin(); iter != m_NeuronGeo.end(); iter++) {
        glUseProgram(m_NeuronProgram->GetProgram());

        GLint modelLoc = glGetUniformLocation(m_NeuronProgram->GetProgram(), "model");
        GLint viewLoc = glGetUniformLocation(m_NeuronProgram->GetProgram(), "view");
        GLint projLoc = glGetUniformLocation(m_NeuronProgram->GetProgram(), "projection");

        glDisable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_DEPTH_TEST);
        glBindVertexArray(iter->second.vao);

        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

        GLint colorLoc = glGetUniformLocation(m_NeuronProgram->GetProgram(), "a_color");
        if(!m_selectMode)
            glUniform4fv(colorLoc, 1, glm::value_ptr(iter->second.color));
        else {
            if(iter->second.selected)
                glUniform4fv(colorLoc, 1, glm::value_ptr(iter->second.color+0.3f));
            else
                glUniform4fv(colorLoc, 1, glm::value_ptr(glm::vec4(0.1,0.1,0.1,0.1)));
        }

        glDrawArrays(GL_LINES, 0, iter->second.geometry->GetVertexSize(Property::Vertex));


        glUseProgram(m_SomaProgram->GetProgram());
        glEnable(GL_DEPTH_TEST);
        glDisable(GL_BLEND);
//        glEnable(GL_CULL_FACE);
//        glCullFace(GL_BACK);
        GLint modelLoc2 = glGetUniformLocation(m_SomaProgram->GetProgram(), "model");
        GLint viewLoc2 = glGetUniformLocation(m_SomaProgram->GetProgram(), "view");
        GLint projLoc2 = glGetUniformLocation(m_SomaProgram->GetProgram(), "projection");
        glBindVertexArray(iter->second.vao_Soma);
        glUniformMatrix4fv(modelLoc2, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(viewLoc2, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projLoc2, 1, GL_FALSE, glm::value_ptr(projection));
        GLint colorLoc2 = glGetUniformLocation(m_SomaProgram->GetProgram(), "a_color");
        glUniform4fv(colorLoc2, 1, &iter->second.color[0]);
        if(!m_selectMode)
            glUniform4fv(colorLoc2, 1, &iter->second.color[0]);
        else {
            if(iter->second.selected)
                glUniform4fv(colorLoc2, 1, glm::value_ptr(iter->second.color+0.3f));
            else
                glUniform4fv(colorLoc2, 1, glm::value_ptr(glm::vec4(0.3,0.3,0.3,0.1)));
        }
        
        GLint centerLoc2 = glGetUniformLocation(m_SomaProgram->GetProgram(), "a_center");

        auto soma = iter->second.geometry->GetChildren()[0];
        Geometry *somageometry = dynamic_cast<Geometry *>(soma.get());
        glm::vec3 *centerp = (glm::vec3 *)somageometry->GetVertexPoint(Property::Other);
        glm::vec4 center{centerp->x, centerp->y, centerp->z, 0};
        glUniform4fv(centerLoc2, 1, glm::value_ptr(center));
        GLint scaleLoc2 = glGetUniformLocation(m_SomaProgram->GetProgram(), "scale");
        GLfloat scale = 1.0f;
        if (m_Species == "monkey") {
            scale = 5.0f;
        }
        glUniform1f(scaleLoc2, scale);

        glDrawArrays(GL_TRIANGLES, 0, somageometry->GetVertexSize(Property::Vertex));
    }
//    glDisableVertexAttribArray(position);
//    glDisableVertexAttribArray(normLoc);

    return true;
}

bool EGLCore::FinishDraw() {
    // The gl function has no return value.
    glFlush();
    glFinish();
    return eglSwapBuffers(m_eglDisplay, m_eglSurface);
}


void EGLCore::Release() {
    if ((nullptr == m_eglDisplay) || (nullptr == m_eglSurface) || (!eglDestroySurface(m_eglDisplay, m_eglSurface))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglDestroySurface failed");
    }

    if ((nullptr == m_eglDisplay) || (nullptr == m_eglContext) || (!eglDestroyContext(m_eglDisplay, m_eglContext))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglDestroyContext failed");
    }

    if ((nullptr == m_eglDisplay) || (!eglTerminate(m_eglDisplay))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglTerminate failed");
    }
}

void EGLCore::addEvent(std::shared_ptr<Event> event) {
    if (m_Manipulator) {
        m_Manipulator->addEvent(event);
    }
}


// 添加到 EGLCore 类成员函数中

// 销毁旧 Surface 和 Context（必要时）
void EGLCore::DestroyPreviousSurface() {
    if (m_eglSurface != EGL_NO_SURFACE) {
        eglDestroySurface(m_eglDisplay, m_eglSurface);
        m_eglSurface = EGL_NO_SURFACE;
    }
    if (m_eglContext != EGL_NO_CONTEXT) {
        eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
//        eglDestroyContext(m_eglDisplay, m_eglContext);
//        m_eglContext = EGL_NO_CONTEXT;
    }
}
void EGLCore::UpdateSize(int width, int height) {
    m_width = width;
    m_height = height;
    if (m_width > 0) {
        m_widthPercent = FIFTY_PERCENT * m_height / m_width;
    }
    projection = glm::perspective(glm::radians(60.0f),              // 视角
                                  (float)m_width / (float)m_height, // 宽高比
                                  m_near, m_far                     // 近截面和远截面
    );
}
// 调整 Surface 大小的核心函数
bool EGLCore::Resize(int newWidth, int newHeight) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "Resize execute, new size: %dx%d", newWidth,
                 newHeight);

    // 校验参数
    if (newWidth <= 0 || newHeight <= 0) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Resize: invalid size");
        return false;
    }

    // 保存当前窗口句柄（假设窗口句柄未改变，仅调整尺寸）
    EGLNativeWindowType window = m_eglWindow;
    if (window == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Resize: window is null");
        return false;
    }

    // 销毁旧 Surface 和 Context（注意：若需保留 Context，可仅销毁 Surface）
    DestroyPreviousSurface();

    // 更新尺寸
    UpdateSize(newWidth, newHeight);

    // 重新创建 Surface
    m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, window, nullptr);
    if (m_eglSurface == EGL_NO_SURFACE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Resize: create new surface failed");
        return false;
    }

    // 重新绑定 Context 到新 Surface
    if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Resize: eglMakeCurrent failed");
        return false;
    }

    // 重置视口
    glViewport(0, 0, newWidth, newHeight);
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "Resize success");
    return true;
}